package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.utils.WeChatPayUtil;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    AddressBookMapper addressBookMapper;

    @Autowired
    ShoppingCartMapper shoppingCartMapper;

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderDetailMapper orderDetailMapper;

    @Autowired
    WeChatPayUtil weChatPayUtil;

    @Autowired
    WebSocketServer webSocketServer;

    //用户下单
    @Override
    public OrderSubmitVO userSubmit(OrdersSubmitDTO ordersSubmitDTO) {
        //异常处理: 判断收货地址是否为空,是否超出配送范围,购物车是否为空
        AddressBook byId = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if (byId == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }
        //获取用户id
        Long currentId = BaseContext.getCurrentId();
        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(currentId);

        //判断购物车是否存在
        List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
        if (list == null || list.size() == 0) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }
        //获取订单数据
        Orders order = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, order);
        order.setPhone(byId.getPhone());
        order.setAddress(byId.getDetail());
        order.setConsignee(byId.getConsignee());
        order.setNumber(String.valueOf(System.currentTimeMillis()));
        order.setUserId(currentId);
        order.setStatus(Orders.PENDING_PAYMENT);
        order.setPayStatus(Orders.UN_PAID);
        order.setOrderTime(LocalDateTime.now());
        //向订单表中插入1条数据
        orderMapper.addOrder(order);
        //获取订单明细数据
        List<OrderDetail> orderDetailList = new ArrayList<>();
        for (ShoppingCart cart : list) {
            OrderDetail orderDetail1 = new OrderDetail();
            BeanUtils.copyProperties(cart, orderDetail1);
            orderDetail1.setOrderId(order.getId());
            orderDetailList.add(orderDetail1);
        }
        //向订单明细表中插入n条数据
        orderDetailMapper.addOrderDetail(orderDetailList);
        //清空购物车数据
        shoppingCartMapper.deleteShopping(currentId);
        //封装返回结果
        OrderSubmitVO build = OrderSubmitVO.builder()
                .id(currentId)
                .orderNumber(order.getNumber())
                .orderTime(order.getOrderTime())
                .orderAmount(order.getAmount())
                .build();
        return build;
    }

    //查询历史订单
    @Override
    public PageResult getHistoryOrders(OrdersPageQueryDTO ordersPageQueryDTO) {
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        //查看订单
        Page<OrderVO> orderVO = orderMapper.getOrdero(ordersPageQueryDTO);
        for (OrderVO vo : orderVO) {
            Long orderId = vo.getId();
            //查看订单明细
            List<OrderDetail> list = orderDetailMapper.getByOrderId(orderId);
            vo.setOrderDetailList(list);
        }
        return new PageResult(orderVO.getTotal(), orderVO.getResult());
    }

    //查看订单详情
    @Override
    public OrderVO getOrderByIdDetail(Long id) {
        OrderVO orders = orderMapper.getOrderByIdDetail(id);
        List<OrderDetail> byOrderId = orderDetailMapper.getByOrderId(id);
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders, orderVO);
        orderVO.setOrderDetailList(byOrderId);
        return orderVO;
    }

    //取消订单
    @Override
    public OrderVO cancelOrder(Long id) {
        OrdersConfirmDTO ordersConfirmDTO = new OrdersConfirmDTO();
        ordersConfirmDTO.setId(id);
        ordersConfirmDTO.setStatus(Orders.CANCELLED);
        orderMapper.canceOrder(ordersConfirmDTO);

        return null;
    }

    //再来一单
    @Override
    public void repetition(Long id) {
        List<OrderDetail> orderDetailList = orderMapper.repetition(id);
        for (OrderDetail orderDetail : orderDetailList) {
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(orderDetail, shoppingCart);
            Long currentId = BaseContext.getCurrentId();
            shoppingCart.setUserId(currentId);
            shoppingCartMapper.addShoppingCart(shoppingCart);
        }
    }

    //订单搜索
    @Override
    public PageResult getOrder(OrdersPageQueryDTO ordersPageQueryDTO) {
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        Page<OrderVO> page = orderMapper.getOrdero(ordersPageQueryDTO);
        List<OrderVO> ordero = page.getResult();
        for (OrderVO orderVO : ordero) {
            Long id = orderVO.getId();
            List<OrderDetail> byOrderId = orderDetailMapper.getByOrderId(id);
            BeanUtils.copyProperties(byOrderId, ordero);
        }
        return new PageResult(page.getTotal(), ordero);
    }

    //各个状态的订单数量统计
    @Override
    public OrderStatisticsVO getStatistics() {

        Integer statistics = orderMapper.getStatistics(Orders.TO_BE_CONFIRMED);
        Integer statistics1 = orderMapper.getStatistics(Orders.CONFIRMED);
        Integer statistics2 = orderMapper.getStatistics(Orders.DELIVERY_IN_PROGRESS);

        OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();
        orderStatisticsVO.setToBeConfirmed(statistics);
        orderStatisticsVO.setConfirmed(statistics1);
        orderStatisticsVO.setDeliveryInProgress(statistics2);


        return orderStatisticsVO;
    }

    //接单
    @Override
    public void confirm(OrdersConfirmDTO ordersConfirmDTO) {
        Orders orders = Orders.builder()
                .id(ordersConfirmDTO.getId())
                .status(Orders.CONFIRMED)
                .build();

        orderMapper.update(orders);
    }

    //拒单
    @Override
    public void rejection(OrdersRejectionDTO ordersRejectionDTO) throws Exception {
        //根据id查询订单
        OrderVO orderByIdDetail = orderMapper.getOrderByIdDetail(ordersRejectionDTO.getId());

        //判断状态是否为2
        if (orderByIdDetail != null && orderByIdDetail.getStatus().equals(Orders.TO_BE_CONFIRMED)) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        //支付状态
        Integer payStatus = orderByIdDetail.getPayStatus();
        if (payStatus == Orders.PAID) {
            //已支付, 退款
            String refund = weChatPayUtil.refund(
                    orderByIdDetail.getNumber(),
                    orderByIdDetail.getNumber(),
                    new BigDecimal(0.01),
                    new BigDecimal(0.01));
            log.info("申请退款: {}", refund);

        }

        Orders orders = new Orders();
        orders.setId(orderByIdDetail.getId());
        orders.setStatus(Orders.CANCELLED);
        orders.setRejectionReason(ordersRejectionDTO.getRejectionReason());
        orders.setCancelTime(LocalDateTime.now());

        orderMapper.update(orders);

    }

    //取消订单
    @Override
    public void cancel(OrdersCancelDTO ordersCancelDTO) throws Exception {
        OrderVO orderByIdDetail = orderMapper.getOrderByIdDetail(ordersCancelDTO.getId());
        //判断是否已经支付
        Integer payStatus = orderByIdDetail.getPayStatus();
        if (payStatus == Orders.PAID) {
            String refund = weChatPayUtil.refund(orderByIdDetail.getNumber(),
                    orderByIdDetail.getNumber(),
                    new BigDecimal(0.01),
                    new BigDecimal(0.01));
            log.info("申请退款: {}", refund);
        }
        Orders orders = new Orders();
        orders.setId(orderByIdDetail.getId());
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelReason(ordersCancelDTO.getCancelReason());
        orders.setCancelTime(LocalDateTime.now());
        orderMapper.update(orders);
    }

    //派送订单
    @Override
    public void delivery(Long id) {
        OrderVO orderByIdDetail = orderMapper.getOrderByIdDetail(id);
        //判断状态是否为4
        if (orderByIdDetail != null && orderByIdDetail.getStatus().equals(Orders.DELIVERY_IN_PROGRESS)) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        Orders orders = new Orders();
        orders.setId(orderByIdDetail.getId());
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
        orderMapper.update(orders);
    }

    //完成订单
    @Override
    public void complete(Long id) {
        OrderVO orderByIdDetail = orderMapper.getOrderByIdDetail(id);
        if (orderByIdDetail != null && orderByIdDetail.getStatus().equals(Orders.COMPLETED)) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        Orders orders = new Orders();
        orders.setId(orderByIdDetail.getId());
        orders.setStatus(Orders.COMPLETED);
        orders.setDeliveryTime(LocalDateTime.now());
        orderMapper.update(orders);
    }

    //催单
    @Override
    public void reminder(Long id) {
        //判断订单是否存在
        Orders orders = orderMapper.getById(id);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        Map map = new HashMap<>();
        map.put("type", 2);
        map.put("orderId", id);
        map.put("content", "订单号：" + orders.getNumber());
        webSocketServer.sendToAllClient(JSON.toJSONString(map));
    }

}
